<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        function Person(name) {
            this.name = name
        }
        const person = new Person()
        // 原型链：
        // ==>规则2 所有的对象都有一个__proto__， 属性值也是一个对象

        console.dir(Person)
        console.dir(person)
        // 1. Person.prototype也是一个对象，所以，它也有__proto__属性, 属性值也是对象。(规则2)
        // console.dir(Person)
        console.log(Person.prototype.__proto__)  // ===> __proto__ 访问到Person.prototype的原型
        // Person.prototype.__proto__ ===> {}   

        // ==> 原型上默认有一个constructor属性，指回的构造函数(我们通过这个知道了Person.prototype的构造函数是Object)

        // ==> 规则4 所有对象的隐式原型指向它的构造函数的显示原型。
        // Person.prototype
        Person.prototype.__proto__ === Object.prototype
        // person.__proto__ === Person.prototype

        //===>  Person.prototype 这个原型对象 是Object这个构造函数创建的'

        // 2. Object它是一个构造函数
        // Object.prototype ===> 得到的也是一个原型，Object构造函数的原型
        // Object.prototype这个原型上默认有一个constructor属性，指向构造函数本身
        Object.prototype.constructor === Object

        // Object.prototype              ==>原型
        // Person.prototype.__proto__    ==>原型
        console.log(Object.prototype)
        console.log(Person.prototype.__proto__)
        // 也就是上面这两个指向的都是 Object 这个构造函数的原型
        console.log(Person.prototype.__proto__ === Object.prototype)

        // 我们说的原型,可以说是构造函数的原型,也可以说实例的原型,指的都是同一个
        // 构造函数 通过 prototype 访问到它的原型
        // 实例    通过 __proto__ 访问到它的原型

        // 3. Object.prototype
        // Object.prototype 它也是一个原型对象, 所以 它也有__proto__属性 
        console.log(Object.prototype)
        console.log(Object.prototype.__proto__ === null)

        // 正常的原型链终止到Object.prototype,  也就是Object.prototype.__proto__ === null
    </script>
</body>

</html>